package com.joe.security.distributed.order.filter;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.joe.security.distributed.order.model.UserDto;
import org.apache.catalina.User;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLDecoder;

/**
 * @Description
 * @Author 高建伟-joe
 * @Date 2023-11-10
 */
@Component
public class TokenAuthenticationFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {

        String payload = httpServletRequest.getHeader("payload");

        if (!StringUtils.isEmpty(payload)){
            // 1. 解析token
            String payloadJson = URLDecoder.decode(payload);
            JSONObject payloadObj = JSON.parseObject(payloadJson);
            UserDto principal = JSONObject.parseObject(payloadObj.getString("user_name"), UserDto.class);

            JSONArray authoritiesArray = payloadObj.getJSONArray("authorities");
            String[] authorities = (String[]) authoritiesArray.toArray(new String[authoritiesArray.size()]);

            // 2. 新建并填充 authentication
            UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(principal, null, AuthorityUtils.createAuthorityList(authorities));
            authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(httpServletRequest));

            // 3.将 authentication 保存进安全上下文
            SecurityContextHolder.getContext().setAuthentication(authentication);
        }
        filterChain.doFilter(httpServletRequest, httpServletResponse);
    }
}
